package cn.wzb.hrm.service.impl;

import cn.wzb.hrm.constants.RedisConstantis;
import cn.wzb.hrm.domain.CourseType;
import cn.wzb.hrm.feignclient.RedisFeignClient;
import cn.wzb.hrm.mapper.CourseTypeMapper;
import cn.wzb.hrm.service.ICourseTypeService;
import cn.wzb.hrm.util.AjaxResult;
import cn.wzb.hrm.vo.CrumbsVo;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import springfox.documentation.spring.web.json.Json;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 课程目录 服务实现类
 * </p>
 *
 * @author whale.chen
 * @since 2020-04-18
 */
@Service
public class CourseTypeServiceImpl extends ServiceImpl<CourseTypeMapper, CourseType> implements ICourseTypeService {

    @Autowired
    private RedisFeignClient redisFeignClient;

    //查询课程分类列表  返回有层级 结构的 List<CourseType>
    @Override
    public List<CourseType> treeData() {
        //查询所有条数--->调缓存查询数据selectCourseTypeFromCache()方法
        List<CourseType> allCourseType = selectCourseTypeFromCache();//baseMapper.selectList(null);

        //一级分类集合
        List<CourseType> firstCourseTypes = new ArrayList<>();
        
        //遍历所有课程,判断是否为一级分类
        //currentCourseType:当前课程类型
        for (CourseType currentCourseType : allCourseType) {
            //判断是否为一级分类
            if(currentCourseType.getPid()==0){
                //将一级分类装入list中
                firstCourseTypes.add(currentCourseType);
            }else{
                //如果不是一级分类，就去找自己的父分类，加入父分类的children
                for (CourseType parentCourseType : allCourseType) {
                    //如果当前分类的pid等于某个分类的id,那么这个分类就是它的父分类
                    if(currentCourseType.getPid().equals(parentCourseType.getId())){
                        //把currentCourseType 当前分类加入 父分类parentCourseType的 children
                        parentCourseType.getChildren().add(currentCourseType);
                        break;
                    }
                }
            }
        }
        return firstCourseTypes;
    }

    @Override
    public List<CrumbsVo> crumbs(Long courseTypeId) {
        //1.根据当前分类ID查询出当前分类： 1040
        CourseType courseType = baseMapper.selectById(courseTypeId);

        //2.获取当前分类的path : .1037.1039.1040.
        String path = courseType.getPath();

        //去掉两边的 “.”   如：  1037.1039.1040.
        path=path.startsWith(".")?path.substring(1):path;
        //1037.1039.1040
        path=path.endsWith(".")?path.substring(0,path.length()-1):path;

        //获取当前分类的path，然后切割成数组(id数组) ：1037.1039.1040  -> [1037 ,1039 ,1040]
        String[] courseTypeIdStr = path.split("\\.");

        List<Long> ids = new ArrayList<>();
        for(String idStr : courseTypeIdStr){
            ids.add(Long.valueOf(idStr));
        }

        //3.通过课程分类的id数组,批量查询课程分类列表 ：[courseType,CourseType,CourseType]
        List<CourseType> courseTypes = baseMapper.selectBatchIds(ids);

        //4.遍历课程分类列表，每个课程分类就是一个CrumbsVo : [CrumbsVo , CrumbsVo, CrumbsVo]
        List<CrumbsVo> result = new ArrayList<>() ;
        courseTypes.forEach( currentCourseType -> {
            //把当前课程分类 currentCourseType ,封装到  CrumbsVo.OwnerProductType
            CrumbsVo  vo = new CrumbsVo();
            vo.setOwnerProductType(currentCourseType);

            //5.为每一个课程类型找他的兄弟姐妹列表，设置到CrumbsVo.otherProductTypes列表中
            Long pid = currentCourseType.getPid();
            List<CourseType> otherProductTypes = baseMapper.selectListByPid(pid);
            vo.setOtherProductTypes(otherProductTypes);
            result.add(vo);
        });

        //6.最后返回结果List
        return result;
    }

    //课程分类缓存到Redis
    private List<CourseType> selectCourseTypeFromCache(){

        //通过RedisFeign查询Redis中的缓存
        AjaxResult ajaxResultFromRedis = redisFeignClient.getString(RedisConstantis.KEY_ALLCOURSETYPE);

        //判断是否有缓存
        if(ajaxResultFromRedis.isSuccess() && ajaxResultFromRedis.getResultObj()!=null){

            //如果有,获取出来
            String jsonString = ajaxResultFromRedis.getResultObj().toString();
            //将string转换为json,并返回
            return JSON.parseArray(jsonString,CourseType.class);
        }
        //缓存中没有数据,就从数据库中查找
        List<CourseType> courseTypes = baseMapper.selectList(null);
        //将list装换为json缓存到Redis中
        AjaxResult ajaxResultToRedis = redisFeignClient.setString(RedisConstantis.KEY_ALLCOURSETYPE, JSON.toJSONString(courseTypes));

        return courseTypes;
    }

    //缓存重置方法抽取
    private AjaxResult resetCache() {
        List<CourseType> courseTypes = baseMapper.selectList(null);

        return redisFeignClient.setString(RedisConstantis.KEY_ALLCOURSETYPE, JSON.toJSONString(courseTypes));
    }

    @Override
    public boolean insert(CourseType entity) {
        //调用父类的insert
        boolean insert = super.insert(entity);
        if(insert){
            //重置Redis
            AjaxResult result = resetCache();

            //判断缓存重置是否成功
            if(!result.isSuccess()){
                throw new RuntimeException("缓存重置失败");
            }
        }
        return insert;
    }



    @Override
    public boolean updateById(CourseType entity) {
        boolean update = super.updateById(entity);
        if(update){
            //重置Redis
            AjaxResult result = resetCache();
            //判断缓存重置是否成功
            if(!result.isSuccess()){
                throw new RuntimeException("缓存重置失败");
            }
        }
        return update;
    }

    @Override
    public boolean deleteById(Serializable id) {
        boolean delete = super.deleteById(id);
        if(delete){
            //重置Redis
            AjaxResult result = resetCache();
            //判断缓存重置是否成功
            if(!result.isSuccess()){
                throw new RuntimeException("缓存重置失败");
            }
        }
        return delete;
    }
}
